package net.zoneland.knowledge.enums;

import net.zoneland.knowledge.constant.Constants;
import net.zoneland.knowledge.controller.bean.UomUserOrgQueryVo;
import net.zoneland.knowledge.model.WorkApplyInfo;
import net.zoneland.knowledge.service.PartyService;
import net.zoneland.knowledge.service.RoleService;
import net.zoneland.uniflow.client.UserInfo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.List;

/**
 * 工单处理状态.
 *
 * @author: zmq
 * 2021/9/29
 */
public enum WorkStatusEnum {

    /**
     * 草稿.
     */
    DRAFT("draft", "拟稿") {

        @Override
        public String getChapterNodeName() {
            return "拟稿";
        }

        /**
         * 下一个提交的任务状态
         * @param useSealType 用章类型
         * @return 任务状态
         */
        @Override
        public WorkStatusEnum getNextSubmitStatus(final String useSealType) {
            return getChapterDraftNextStatus(useSealType);
        }

        @Override
        public UserInfo getHandler(WorkApplyInfo workApplyInfo) {
            return new UserInfo(workApplyInfo.getCreatorUid(), workApplyInfo.getCreatorName());
        }
    },

    /**
     * 部门管理员审批.
     */
    DEPT_ADMIN_APPROVE("deptAdminApprove", "部门管理员审批"),

    /**
     * 分派办理，发起子流程，待办都在子流程中，当前工单无待办.
     * <p>自动节点</p>
     */
    CREATE_SUB_FLOW("createSubFlow", "分派办理"),
    /**
     * 办理，原责任人审批.
     */
    RESPONDER_APPROVE("responderApprove", "办理"),
    /**
     * 办结确认，指分任务都确认完了、结束主工单之前的状态.
     */
    FINISH_CONFIRM("finishConfirm", "办结确认"),
    /**
     * 办理，原子流程-组织人员办理.
     */
    SUB_ORG_USER_HANDLE("orgUserHandle", "办理"),
    /**
     * 分派办理，原子流程-分任务办理子流程.
     * <p>自动节点</p>
     */
    SUB_CREATE_SUB_FLOW("subCreateSubFlow", "分派办理"),
    /**
     * 办理，原子流程-组织人员确认.
     */
    SUB_ORG_USER_CONFIRM("orgUserConfirm", "办理"),
    /**
     * 待确认，原子流程-拟稿人确认.
     * <p>待办挂起</p>
     */
    SUB_CREATOR_CONFIRM("creatorConfirm", "待确认"),

    /**
     *书记.
     */
    ZBSJ("zbsj", "书记审批") {

        /**
         * 需要特殊处理的部门-市场经营部总支部.
         */
        private static final String SCJYB = "中国共产党中国移动通信集团浙江有限公司市场经营部总支部委员会";

        /**
         * 指定受理的书记ID.
         */
        private static final String USER_ID = "zhengjn";

        /**
         * 指定受理的书记名称.
         */
        private static final String USER_NAME = "郑江南";

        /**
         * 下一个提交的任务状态
         * @param useSealType 用章类型
         * @return 任务状态
         */
        @Override
        public WorkStatusEnum getNextSubmitStatus(final String useSealType) {
            return ZSDWJBR;
        }

        /**
         * 退回上一步的任务状态
         * @param useSealType 用章类型
         * @return 任务状态
         */
        @Override
        public WorkStatusEnum getRejectStatus(final String useSealType) {
            return DRAFT;
        }
        @Override
        public UserInfo getHandler(WorkApplyInfo workApplyInfo) {
            if (SCJYB.equals(workApplyInfo.getCreatorPartyOrgName())) {
                // 当登录人所在党组织为该组织时, 书记审批处理人固化为指定人员, userId为oaId
               return new UserInfo(USER_ID, USER_NAME);
            }
            String creatorPartyOrgUuid = workApplyInfo.getCreatorPartyOrgUuid();
            if (StringUtils.isBlank(creatorPartyOrgUuid)) {
                final UomUserOrgQueryVo condition = new UomUserOrgQueryVo();
                condition.setOaId(workApplyInfo.getCreatorUid());
                condition.setIgnoreHiddenInfo(true);
                condition.setDoNotfillMore(true);
                return partyService.searchByCondition(condition).stream()
                    .findFirst()
                    .map(item -> roleService.getDwsjByOrgUuid(item.getOrgUUID()))
                    .orElse(null);

            }
            return roleService.getDwsjByOrgUuid(creatorPartyOrgUuid);
        }
    },

    /**
     *直属党委经办人
     */
    ZSDWJBR("zsdwjbr", "直属党委经办人办理") {

        /**
         * 下一个提交的任务状态
         * @param useSealType 用章类型
         * @return 任务状态
         */
        @Override
        public WorkStatusEnum getNextSubmitStatus(final String useSealType) {
            return ZSDWFZR;
        }

        /**
         * 退回上一步的任务状态
         * @param useSealType 用章类型
         * @return 任务状态
         */
        @Override
        public WorkStatusEnum getRejectStatus(final String useSealType) {
            return ZBSJ;
        }
        @Override
        public UserInfo getHandler(WorkApplyInfo workApplyInfo) {
            List<UserInfo> users = roleService.getUserInfoFromRole(Constants.ROLE_ZSDWJBR);
            return users.stream().findFirst().orElse(null);
        }
    },

    /**
     *直属党委负责人
     */
    ZSDWFZR("zsdwfzr", "直属党委负责人审批") {

        /**
         * 下一个提交的任务状态
         * @param useSealType 用章类型
         * @return 任务状态
         */
        @Override
        public WorkStatusEnum getNextSubmitStatus(final String useSealType) {
            return END;
        }
        @Override
        public UserInfo getHandler(WorkApplyInfo workApplyInfo) {
            return new UserInfo(workApplyInfo.getPartyLeaderUid(), workApplyInfo.getPartyLeaderName());
        }

        /**
         * 退回上一步的任务状态
         * @param useSealType 用章类型
         * @return 任务状态
         */
        @Override
        public WorkStatusEnum getRejectStatus(final String useSealType) {
            return getChapterZsdwfzrRejectStatus(useSealType);
        }
    },

    /**
     * 相关主管部门经办人审核.
     */
    COMPETENT_DEPARTMENTS_AUDIT("competentDepartmentsAudit", "相关主管部门经办人审核"),

    /**
     * 各党（总）支部书记审批.
     */
    PARTY_SECRETARY_APPROVE("partySecretaryApprove", "各党（总）支部书记审批") {
        /**
         * 需要特殊处理的部门-市场经营部总支部.
         */
        private static final String SCJYB = "中国共产党中国移动通信集团浙江有限公司市场经营部总支部委员会";

        /**
         * 指定受理的书记ID.
         */
        private static final String USER_ID = "zhengjn";

        /**
         * 指定受理的书记名称.
         */
        private static final String USER_NAME = "郑江南";
        @Override
        public UserInfo getHandler(WorkApplyInfo workApplyInfo) {
            if (SCJYB.equals(workApplyInfo.getCreatorPartyOrgName())) {
                // 当登录人所在党组织为该组织时, 书记审批处理人固化为指定人员, userId为oaId
                return new UserInfo(USER_ID, USER_NAME);
            }
            String creatorPartyOrgUuid = workApplyInfo.getCreatorPartyOrgUuid();
            if (StringUtils.isBlank(creatorPartyOrgUuid)) {
                final UomUserOrgQueryVo condition = new UomUserOrgQueryVo();
                condition.setOaId(workApplyInfo.getCreatorUid());
                condition.setIgnoreHiddenInfo(true);
                condition.setDoNotfillMore(true);
                return partyService.searchByCondition(condition).stream()
                    .findFirst()
                    .map(item -> roleService.getDwsjByOrgUuid(item.getOrgUUID()))
                    .orElse(null);

            }
            return roleService.getDwsjByOrgUuid(creatorPartyOrgUuid);
        }
    },

    /**
     * 分管领导（省） 党办（地市）审批.
     */
    RESPONSIBLE_LEADER_APPROVE("responsibleLeaderApprove", "分管领导（省） 党办（地市）审批"),

    /**
     * 省公司职能部门审核.
     */
    FUNCTIONAL_DEPARTMENT_AUDIT("functionalDepartmentAudit", "省公司职能部门审核"),

    /**
     * 公司党委会审议.
     */
    PARTY_COMMITTEE_DELIBERATION("partyCommitteeDeliberation", "公司党委会审议"),

    /**
     * END.
     */
    END("_EOF", "结束"),

    /**
     * 不属于审批环节，只用于页面显示逻辑.
     */
    DISPLAY_DEAL("DISPLAY_DEAL", "办理"),

    /**
     * 不属于审批环节，只用于页面显示逻辑.
     */
    DISPLAY_CONFIRM("DISPLAY_CONFIRM", "待确认"),

    /**
     * 不属于审批环节，只用于页面显示逻辑.
     */
    DISPLAY_DEALING("DISPLAY_DEALING", "办理中"),

    /**
     * 不属于审批环节，只用于页面显示逻辑.
     */
    DISPLAY_FINISH("DISPLAY_FINISH", "完成"),

    /**
     * 结办，不属于审批环节，只用于页面显示逻辑.
     * 工单拟搞人点结办后的状态. 没有任务待办
     */
    DISPLAY_TERMINATE("DISPLAY_TERMINATE", "报结"),

    /**
     * 不属于审批环节，只用于页面显示逻辑.
     */
    DISPLAY_COMPLETE("DISPLAY_COMPLETE", "办结");

    /**
     * 构造.
     * @param value 值
     * @param name 名称
     */
    WorkStatusEnum(final String value, final String name) {
        this.value = value;
        this.name = name;
    }

    private static RoleService roleService;

    private static PartyService partyService;

    /**
     * 下一个提交的任务状态
     * @param useSealType 用章类型
     * @return 任务状态
     */
    public WorkStatusEnum getNextSubmitStatus(final String useSealType) {
        return null;
    }

    /**
     * 退回上一步的任务状态
     * @param useSealType 用章类型
     * @return 任务状态
     */
    public WorkStatusEnum getRejectStatus(final String useSealType) {
        return null;
    }

    /**
     * 获取节点处理
     * @param workApplyInfo
     * @return
     */
    public UserInfo getHandler(WorkApplyInfo workApplyInfo) {
        return null;
    }

    /**
     * 获取印章申请流程定义的名称
     * @return
     */
    public String getChapterNodeName() {
        return this.name;
    }
    /**
     * key.
     */
    private String value;

    /**
     * label.
     */
    private String name;

    /**
     * .
     *
     * @return value
     */
    public String getValue() {
        return value;
    }

    /**
     * .
     *
     * @return name
     */
    public String getName() {
        return name;
    }

    public static WorkStatusEnum getByValue(String value) {
        for (WorkStatusEnum categoryEnum : WorkStatusEnum.values()) {
            if (categoryEnum.value.equals(value)) {
                return categoryEnum;
            }
        }
        return null;
    }

    /**枚举内部static类，对枚举内的Mapper或Server赋值**/
    @Component
    public static class WorkStatusEnumInjector {

        @Autowired
        private RoleService roleService;

        @Autowired
        private PartyService partyService;

        @PostConstruct
        public void postConstruct() {
            WorkStatusEnum.roleService = roleService;
            WorkStatusEnum.partyService = partyService;
        }

    }

    /**
     * 获取用章申请流程在拟稿节点的下一个任务状态
     * @param useSealType 用章类型
     * @return 任务状态
     */
    public static WorkStatusEnum getChapterDraftNextStatus(final String useSealType) {
        // 如果用章类型是直属党委用章，则下一个任务状态是直属党委负责人，否则任务状态是书记
        if(StringUtils.equals(useSealType, "partyCommittee")) {
            return WorkStatusEnum.ZSDWFZR;
        }
        return WorkStatusEnum.ZBSJ;
    }

    /**
     * 获取用章申请流程在直属党委负责人节点的上一个任务状态
     * @param useSealType 用章类型
     * @return 任务状态
     */
    public static WorkStatusEnum getChapterZsdwfzrRejectStatus(final String useSealType) {
        // 如果用章类型是直属党委用章，则上一个任务状态是拟稿，否则任务状态是直属党委经办人
        if(StringUtils.equals(useSealType, "partyCommittee")) {
            return WorkStatusEnum.DRAFT;
        }
        return WorkStatusEnum.ZSDWJBR;
    }

}
